package com.matrix.core.exception;

import com.alibaba.fastjson.support.spring.FastJsonJsonView;
import com.matrix.core.constance.SystemErrorCode;
import com.matrix.core.tools.*;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * @description 全局异常处理类
 * @author 姜友瑶
 * @data 2016-06-26
 */
@Service("GlobleExceptionResolver")
public class GlobleExceptionResolver implements HandlerExceptionResolver {

	private static final String TRUE = "true";

	@Override
	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
                                         Exception ex) {
		ModelAndView model = new ModelAndView();
		FastJsonJsonView view = new FastJsonJsonView();
		Map<String, Object> attr = new HashMap<>(10);

		if (ex instanceof GlobleException) {
			// 如果是内部全局异常
			LogUtil.warn("#程序抛出全局异常#", ex);
			GlobleException globleException = (GlobleException) ex;
			attr.put("status", globleException.getErrorCode());
			attr.put("info", globleException.getMessage());

		} else {

			// 非内部异常
			LogUtil.error("#程序抛出未捕获异常#", ex);
			attr.put("status", 999999);
			attr.put("info", InternationaUtil.getMesssge(SystemErrorCode.SYSTEM_UNKNOW_ERROR));
			// 发送异常信息到管理群 
			// 加上请求接口路径 
			String requestUrl="";
			if(null!=request) {
				StringBuffer requestUrlBuffer = request.getRequestURL();
				if(null!=requestUrlBuffer && StringUtils.isNotBlank(requestUrlBuffer.toString())) {
					// 判断非空后加入到异常信息中
					requestUrl = requestUrlBuffer.toString();
				}
			}
			
			sendNoticeToAdmin(ex, MdcUtil.getMdc(),requestUrl);

		}
		attr.put("MDC", MdcUtil.getMdc());
		view.setAttributesMap(attr);
		model.setView(view);
		return model;
	}

	/**
	 * 发送异常信息到管理群
	 * 
	 * @author JIANGYOUYAO
	 * @email 935090232@qq.com
	 * @date 2018年5月9日
	 * @param ex
	 */
	public static void sendNoticeToAdmin(Exception ex, String mdc,String requestUrl) {
		String isOpenDingdingExceptionNotice = PropertiesUtil.getString("is_open_exception_report");

		if (isOpenDingdingExceptionNotice != null && TRUE.equals(isOpenDingdingExceptionNotice)) {
			String simpleMsg=ex.getMessage();
			if(StringUtils.isNotBlank(simpleMsg) && simpleMsg.length()>100){
				simpleMsg=simpleMsg.substring(0,100);
			}
			LogUtil.info("上报异常通知");
			String projNo = PropertiesUtil.getString("projNo");
			String owner = PropertiesUtil.getString("owner");
			String exceptionCenterUrl = PropertiesUtil.getString("exception_center_url");
			String contetn="machine="+ ComputerTools.getHostName()+"&owner="+owner+"&errorMsg="+printStackTraceToString(ex)+"&projNo="+projNo
					+"&exceptionType="+ex.getClass().getName()+"&simpleMsg="+ simpleMsg
					+"&mdc="+mdc+" url="+requestUrl;
			ExceptionReportUtil.sendMsg(exceptionCenterUrl, contetn);
		}
	}

	
	/**
	 * 获取异常堆栈信息
	 * 
	 * @author JIANGYOUYAO
	 * @email 935090232@qq.com
	 * @date 2018年5月9日
	 * @param t
	 * @return
	 */
	public static String printStackTraceToString(Throwable t) {
		StringWriter sw = new StringWriter();
		t.printStackTrace(new PrintWriter(sw, true));
		return sw.getBuffer().toString();
	}

}
